﻿using IRepository;
using IServices;
using Model.Dto;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Services
{
    /// <summary>
    /// 基础业务层实现类
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    public class BaseServices<TEntity> : IBaseServices<TEntity> where TEntity : class, new()
    {
        public IBaseRepository<TEntity> BaseDao;//通过在子类的构造函数中注入，这里是基类，不用构造函数

        #region 新增

        #region 单条数据新增
        /// <summary>
        /// 单条数据新增
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> Add(TEntity model)
        {
            return await BaseDao.Add(model);
        }
        #endregion

        #region 批量新增
        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<bool> AddRange(List<TEntity> list)
        {
            return await BaseDao.AddRange(list);
        }
        #endregion

        #endregion

        #region 删除
        #region 单条数据删除
        /// <summary>
        ///  单条数据删除
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> Delete(TEntity model)
        {
            return await BaseDao.Delete(model);
        }
        #endregion

        #region 批量删除
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="sqlWhere"></param>
        /// <returns>返回受影响的行数</returns>
        public async Task<int> BatchDelete(Expression<Func<TEntity, bool>> sqlWhere)
        {
            return await BaseDao.BatchDelete(sqlWhere);
        }
        #endregion

        #endregion

        #region  查询 注：AsNoTracking无跟踪查询提高查询性能

        #region 查询当前实体所有数据
        /// <summary>
        /// 查询所有数据
        /// </summary>
        /// <returns></returns>
        public async Task<List<TEntity>> GetList()
        {
            return await BaseDao.GetList();
        }
        #endregion    

        #region 根据查询条件查询集合
        /// <summary>
        /// 根据查询条件查询集合
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public async Task<List<TEntity>> GetByList(Expression<Func<TEntity, bool>> whereLambda)
        {
            return await BaseDao.GetByList(whereLambda);
        }
        #endregion

        #region 根据查询条件查询第一个条数据
        /// <summary>
        /// 根据查询条件查询第一个条数据
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public async Task<TEntity> GetByIdFirstModel(Expression<Func<TEntity, bool>> whereLambda)
        {
            return await BaseDao.GetByIdFirstModel(whereLambda);
        }
        #endregion

        #region 根据查询条件并单方向排序
        /// <summary>
        /// 根据查询条件并单方向排序
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda">排序字段</param>
        /// <param name="isAsc">排序方向</param>
        /// <returns></returns>
        public async Task<List<TEntity>> GetByList<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true)
        {
            return await BaseDao.GetByList(whereLambda, orderLambda, isAsc);
        }
        #endregion

        #region 根据查询条件并单方向排序取得前几条数据
        /// <summary>
        /// 根据查询条件并单方向排序取得前几条数据
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="top">取得第几条数据</param>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda">排序字段</param>
        /// <param name="isAsc">排序方向</param>
        /// <returns></returns>
        public async Task<List<TEntity>> GetByList<TKey>(int top, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderLambda, bool isAsc = true)
        {
            return await BaseDao.GetByList(top, whereLambda, orderLambda, isAsc);
        }
        #endregion


        #region 根据条件排序查询  双排序 
        /// <summary>
        /// 根据条件排序查询  双排序
        /// </summary>
        /// <typeparam name="TKey1"></typeparam>
        /// <typeparam name="TKey2"></typeparam>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda1">排序字段</param>
        /// <param name="orderLambda2">排序字段</param>
        /// <param name="isAsc1">排序方向</param>
        /// <param name="isAsc2">排序方向</param>
        /// <returns></returns>
        public async Task<List<TEntity>> GetByList<TKey1, TKey2>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey1>> orderLambda1, Expression<Func<TEntity, TKey2>> orderLambda2, bool isAsc1 = true, bool isAsc2 = true)
        {
            return await BaseDao.GetByList(whereLambda, orderLambda1, orderLambda2, isAsc1, isAsc2);
        }
        #endregion

        #region 根据条件排序查询Top个数  双排序 
        /// <summary>
        /// 根据条件排序查询Top个数  双排序
        /// </summary>
        /// <typeparam name="TKey1"></typeparam>
        /// <typeparam name="TKey2"></typeparam>
        /// <param name="top">取得前几条数据</param>
        /// <param name="whereLambda">查询条件</param>
        /// <param name="orderLambda1">排序字段</param>
        /// <param name="orderLambda2">排序字段</param>
        /// <param name="isAsc1">排序方向</param>
        /// <param name="isAsc2">排序方向</param>
        /// <returns></returns>
        public async Task<List<TEntity>> GetByList<TKey1, TKey2>(int top, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey1>> orderLambda1, Expression<Func<TEntity, TKey2>> orderLambda2, bool isAsc1 = true, bool isAsc2 = true)
        {
            return await BaseDao.GetByList(top, whereLambda, orderLambda1, orderLambda2, isAsc1, isAsc2);
        }
        #endregion

        #endregion

        #region 更新

        #region 更新实体
        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> Modify(TEntity model)
        {
            return await BaseDao.Modify(model);
        }
        #endregion

        #region 根据指定的属性更新实体
        /// <summary>
        /// 根据指定的属性更新实体
        /// </summary>
        /// <param name="model">修改实体</param>
        /// <param name="propertyName">可修改指定属性</param>
        /// <returns></returns>
        public async Task<int> Modify(TEntity model, params string[] propertyNames)
        {
            return await BaseDao.Modify(model, propertyNames);
        }
        #endregion

        #region 根据指定的属性批量更新实体
        /// <summary>
        /// 根据指定的属性批量更新实体
        /// </summary>
        /// <param name="model">更新的数据</param>
        /// <param name="whereLambda">更新的条件</param>
        /// <param name="modifiedPropertyNames">要更新的字段</param>
        /// <returns></returns>
        public async Task<int> BatchModify(TEntity model, Expression<Func<TEntity, bool>> whereLambda, params string[] modifiedPropertyNames)
        {
            return await BaseDao.BatchModify(model, whereLambda, modifiedPropertyNames);
        }
        #endregion

        #endregion


        #region 分页

        #region 6.0 分页查询 一定注意： Skip 之前一定要 OrderBy
        /// <summary>
        /// 分页查询 + List<TEntity> GetPagedList
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">每页多少条数据</param>
        /// <param name="whereLambda">条件 lambda表达式</param>
        /// <param name="orderBy">排序 lambda表达式</param>
        /// <returns></returns>
        public async Task<List<TEntity>> GetPagedList<TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true)
        {
            return await BaseDao.GetPagedList(pageIndex, pageSize, whereLambda, orderByLambda, isAsc);
        }
        #endregion

        #region 6.1分页查询 带输出
        /// <summary>
        /// 分页查询 带输出
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">每页多少条数据</param>
        ///// <param name="rowCount">根据每页多少个算出总共分多少页</param>
        /// <param name="whereLambda">条件</param>
        ///// <param name="orderBy">排序</param>
        /// <param name="isAsc">排序方向</param>
        /// <returns></returns>
        public async Task<PageDto<TEntity>> GetPagedList<TKey>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TKey>> orderByLambda, bool isAsc = true, int pageIndex = 1, int pageSize = 20)
        {
            return await BaseDao.GetPagedList(whereLambda, orderByLambda, isAsc, pageIndex, pageSize);
        }
        #endregion

        #endregion

        #region
        /// <summary>
        /// 回滚
        /// </summary>
        public void RollBackChanges()
        {
            BaseDao.RollBackChanges();
        }
        #endregion
    }
}
